package com.xxl.job.core.rpc.netcom.jetty.server;

import com.xxl.job.core.rpc.codec.RpcRequest;
import com.xxl.job.core.rpc.codec.RpcResponse;
import com.xxl.job.core.rpc.netcom.NetComServerFactory;
import com.xxl.job.core.rpc.serialize.HessianSerializer;
import com.xxl.job.core.util.HttpClientUtil;

import lombok.extern.slf4j.Slf4j;

import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;

/**
 * jetty handler
 * @author xuxueli 2015-11-19 22:32:36
 */
@Slf4j
public class JettyServerHandler extends AbstractHandler {
	
	@Override
	public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		// invoke
        RpcResponse rpcResponse = this.doInvoke(request);

        // serialize response
        byte[] responseBytes = HessianSerializer.serialize(rpcResponse);
		
		response.setContentType("text/html;charset=utf-8");
		response.setStatus(HttpServletResponse.SC_OK);
		baseRequest.setHandled(true);
		
		OutputStream out = response.getOutputStream();
		out.write(responseBytes);
		out.flush();
	}

	private RpcResponse doInvoke(HttpServletRequest request) {
		try {
			// deserialize request
			byte[] requestBytes = HttpClientUtil.readBytes(request);
			if (requestBytes == null || requestBytes.length==0) {
				RpcResponse rpcResponse = new RpcResponse();
				rpcResponse.setError("RpcRequest byte[] is null");
				return rpcResponse;
			}
			RpcRequest rpcRequest = (RpcRequest) HessianSerializer.deserialize(requestBytes);

			/**
			 *  RpcRequest(
			 *  	serverAddress=172.20.14.38:9997,
			 *  	createMillisTime=1529058480034,
			 *  	accessToken=null, 
			 *  	className=com.xxl.job.core.biz.ExecutorBiz,
			 *  	methodName=run,
			 *  	parameterTypes=[class com.xxl.job.core.biz.model.TriggerParam], 
			 *  	parameters=[
			 *  		TriggerParam(
			 *  			jobId=1,
			 *  		    executorHandler=simpleJobHandler,
			 *  		    executorParams=abcd,
			 *  			executorBlockStrategy=SERIAL_EXECUTION,
			 *  			logId=76,
			 *  			logDateTim=1529058480034,
			 *  			glueType=BEAN, 
			 *  			glueSource=,
			 *  			glueUpdatetime=1528954617000, 
			 *  			broadcastIndex=0,
			 *  			broadcastTotal=1
			 *      )]
			 *  )
			 */
			log.info("收到调度中心的调度请求处理, className: [{}], methodName: [{}]",rpcRequest.getClassName(),rpcRequest.getMethodName());
			// invoke
			RpcResponse rpcResponse = NetComServerFactory.invokeService(rpcRequest);
			
			log.info("收到调度中心的调度请求处理完成, request : [{}],response : [{}]",rpcRequest,rpcResponse);
			return rpcResponse;
		} 
		catch (Exception e) {
			log.error(e.getMessage(), e);

			RpcResponse rpcResponse = new RpcResponse();
			rpcResponse.setError("Server-error:" + e.getMessage());
			return rpcResponse;
		}
	}
	
}